トラックパッドのジェスチャで GestureRecognizer をトリガーできる
まとめ
ほとんどのプラットフォームでトラックパッド ジェスチャが送信されるようになりましたPointerPanZoom
シーケンスと
パン、ドラッグ、スケールをトリガーできますGestureRecognizer
コールバック。
コンテクスト
バージョン 3.3.0 より前の Flutter Desktop でのスクロールPointerScrollEvent
離散スクロール デルタを表すメッセージ。このシステムはマウスでうまく機能しました
スクロールホイールもありましたが、トラックパッドのスクロールには適していませんでした。トラックパッドのスクロール
勢いはスクロールデルタだけではなく、
トラックパッドから指を離すタイミングも同様です。
また、トラックパッドのピンチによるズームも表現できませんでした。
3つの新しいPointerEvent
が導入されました:PointerPanZoomStartEvent
、PointerPanZoomUpdateEvent
、 とPointerPanZoomEndEvent
。
関連するGestureRecognizer
への関心を登録するために更新されました
トラックパッド ジェスチャ シーケンス、および放出されますonDrag
、onPan
、および/またはonScale
動きに応じたコールバック
トラックパッド上で 2 本以上の指で操作します。
これは、タッチ操作専用に設計されたコードが、次のような場合にトリガーされる可能性があることを意味します。 トラックパッドの操作と、すべてのデスクトップのスクロールを処理するように設計されたコード トラックパッドのスクロールではなく、マウスのスクロール時にのみトリガーされるようになりました。
変更内容の説明
Flutter エンジンは、すべてのプラットフォームで認識できるように更新されました。
トラックパッド ジェスチャを取得し、それを次のようにフレームワークに送信します。PointerPanZoom
イベント
としてではなくPointerScrollSignal
イベント。PointerScrollSignal
イベントは
マウスホイールのスクロールを表すために今でも使用されています。
プラットフォームと特定のトラックパッド モデルによっては、新しいシステムが機能しない可能性があります。
プラットフォーム API によって Flutter エンジンに十分なデータが提供されない場合に使用されます。
これには Windows も含まれます。Windows では、トラックパッド ジェスチャのサポートは
トラックパッドのドライバーと Web プラットフォームでは、十分なデータが提供されません。
ブラウザ API とトラックパッドのスクロールは依然として必要です
古いものを使うPointerScrollSignal
システム。
開発者は、両方のタイプのイベントを受け取る準備をしておく必要があります。 アプリまたはパッケージが適切な方法でそれらを処理することを確認します。
Listener
には 3 つの新しいコールバックが追加されました。onPointerPanZoomStart
、onPointerPanZoomUpdate
、 とonPointerPanZoomEnd
どれができるか
トラックパッドのスクロールおよびズーム イベントを観察するために使用されます。
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Listener(
onPointerSignal: (PointerSignalEvent event) {
if (event is PointerScrollEvent) {
debugPrint('mouse scrolled ${event.scrollDelta}');
}
},
onPointerPanZoomStart: (PointerPanZoomStartEvent event) {
debugPrint('trackpad scroll started');
},
onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) {
debugPrint('trackpad scrolled ${event.panDelta}');
},
onPointerPanZoomEnd: (PointerPanZoomEndEvent event) {
debugPrint('trackpad scroll ended');
},
child: Container()
);
}
}
PointerPanZoomUpdateEvent
が含まれていますpan
累積を表すフィールド
現在のジェスチャのパン、panDelta
違いを表すフィールド
最後のイベント以降のパン、scale
累積ズームを表すイベント
現在のジェスチャの、およびrotation
イベントへ
現在のジェスチャの累積回転 (ラジアン単位) を表します。
GestureRecognizer
1 つのトラックパッド イベントに対するすべてのメソッドが追加されました。
連続トラックパッドジェスチャ。電話をかけるaddPointerPanZoom
のメソッドGestureRecognizer
とともにPointerPanZoomStartEvent
認識機能が発生します
トラックパッドのインタラクションへの関心を登録し、競合を解決します。
複数の間GestureRecognizer
に応答する可能性のあるもの
ジェスチャー。
次の例は、の適切な使用法を示しています。Listener
とGestureRecognizer
トラックパッドの操作に応答します。
void main() => runApp(Foo());
class Foo extends StatefulWidget {
late final PanGestureRecognizer recognizer;
@override
void initState() {
super.initState();
recognizer = PanGestureRecognizer()
..onStart = _onPanStart
..onUpdate = _onPanUpdate
..onEnd = _onPanEnd;
}
void _onPanStart(DragStartDetails details) {
debugPrint('onStart');
}
void _onPanUpdate(DragUpdateDetails details) {
debugPrint('onUpdate');
}
void _onPanEnd(DragEndDetails details) {
debugPrint('onEnd');
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: recognizer.addPointer,
onPointerPanZoomStart: recognizer.addPointerPanZoom,
child: Container()
);
}
}
使用するときGestureDetector
、これは自動的に行われるため、次のようなコードを記述します。
次の例では、両方の応答に応じてジェスチャ更新コールバックを発行します。
タッチとトラックパッドのパン。
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: (details) {
debugPrint('onStart');
},
onPanUpdate: (details) {
debugPrint('onUpdate');
},
onPanEnd: (details) {
debugPrint('onEnd');
}
child: Container()
);
}
}
移行ガイド
移行手順は、各ジェスチャ操作を必要かどうかによって異なります。 アプリをトラックパッド経由で使用できるようにするか、またはトラックパッドのみに制限する必要があるか タッチとマウスの使い方。
トラックパッドの使用に適したジェスチャ操作用
GestureDetector
使用する変更の必要はありませんが、GestureDetector
トラックパッドを自動的に処理する
ジェスチャ イベントを生成し、認識された場合はコールバックをトリガーします。
GestureRecognizer
とListener
使用する確認しておいてonPointerPanZoomStart
に渡されます
からの各認識器Listener
。
のaddPointerPanZoom
`GestureRecognizer のメソッドを呼び出す必要があります
興味を示し、各トラックパッドのジェスチャの追跡を開始します。
移行前のコード:
void main() => runApp(Foo());
class Foo extends StatefulWidget {
late final PanGestureRecognizer recognizer;
@override
void initState() {
super.initState();
recognizer = PanGestureRecognizer()
..onStart = _onPanStart
..onUpdate = _onPanUpdate
..onEnd = _onPanEnd;
}
void _onPanStart(DragStartDetails details) {
debugPrint('onStart');
}
void _onPanUpdate(DragUpdateDetails details) {
debugPrint('onUpdate');
}
void _onPanEnd(DragEndDetails details) {
debugPrint('onEnd');
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: recognizer.addPointer,
child: Container()
);
}
}
移行後のコード:
void main() => runApp(Foo());
class Foo extends StatefulWidget {
late final PanGestureRecognizer recognizer;
@override
void initState() {
super.initState();
recognizer = PanGestureRecognizer()
..onStart = _onPanStart
..onUpdate = _onPanUpdate
..onEnd = _onPanEnd;
}
void _onPanStart(DragStartDetails details) {
debugPrint('onStart');
}
void _onPanUpdate(DragUpdateDetails details) {
debugPrint('onUpdate');
}
void _onPanEnd(DragEndDetails details) {
debugPrint('onEnd');
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: recognizer.addPointer,
onPointerPanZoomStart: recognizer.addPointerPanZoom,
child: Container()
);
}
}
Listener
生で使用するPointerScrollSignal を使用する次のコードは、すべての場合に呼び出されなくなります。
デスクトップのスクロール。PointerPanZoomUpdate
受信するにはイベントをキャプチャする必要があります
トラックパッドのジェスチャ データ。
移行前のコード:
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Listener(
onPointerSignal: (PointerSignalEvent event) {
if (event is PointerScrollEvent) {
debugPrint('scroll wheel event');
}
}
child: Container()
);
}
}
移行後のコード:
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Listener(
onPointerSignal: (PointerSignalEvent event) {
if (event is PointerScrollEvent) {
debugPrint('scroll wheel event');
}
},
onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) {
debugPrint('trackpad scroll event');
}
child: Container()
);
}
}
ご注意:生のままの使用Listener
このようにして
他のジェスチャ インタラクションと競合が発生するため、
ジェスチャー曖昧さ回避の分野には参加しません。
トラックパッドの使用に適さないジェスチャ操作の場合
GestureDetector
使用するFlutter 3.3.0を使用している場合、RawGestureDetector
使用することができます
それ以外のGestureDetector
それぞれを確実にするためにGestureRecognizer
作成した
によってGestureDetector
もっているsupportedDevices
に設定
除外するPointerDeviceKind.trackpad
。
バージョン 3.4.0 以降、supportedDevices
パラメータ
直接1283219d-146a-4a7e-ae37-ee3289eb73d6。
移行前のコード:
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: (details) {
debugPrint('onStart');
},
onPanUpdate: (details) {
debugPrint('onUpdate');
},
onPanEnd: (details) {
debugPrint('onEnd');
}
child: Container()
);
}
}
移行後のコード (Flutter 3.3.0):
// Example of code after the change.
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: {
PanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
() => PanGestureRecognizer(
supportedDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
// Do not include PointerDeviceKind.trackpad
}
),
(recognizer) {
recognizer
..onStart = (details) {
debugPrint('onStart');
}
..onUpdate = (details) {
debugPrint('onUpdate');
}
..onEnd = (details) {
debugPrint('onEnd');
};
},
),
},
child: Container()
);
}
}
移行後のコード: (Flutter 3.4.0):
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
supportedDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
// Do not include PointerDeviceKind.trackpad
},
onPanStart: (details) {
debugPrint('onStart');
},
onPanUpdate: (details) {
debugPrint('onUpdate');
},
onPanEnd: (details) {
debugPrint('onEnd');
}
child: Container()
);
}
}
RawGestureRecognizer
使用する次のことを明示的に保証しますsupportedDevices
含まないPointerDeviceKind.trackpad
。
移行前のコード:
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: {
PanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
() => PanGestureRecognizer(),
(recognizer) {
recognizer
..onStart = (details) {
debugPrint('onStart');
}
..onUpdate = (details) {
debugPrint('onUpdate');
}
..onEnd = (details) {
debugPrint('onEnd');
};
},
),
},
child: Container()
);
}
}
移行後のコード:
// Example of code after the change.
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: {
PanGestureRecognizer:
GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
() => PanGestureRecognizer(
supportedDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
// Do not include PointerDeviceKind.trackpad
}
),
(recognizer) {
recognizer
..onStart = (details) {
debugPrint('onStart');
}
..onUpdate = (details) {
debugPrint('onUpdate');
}
..onEnd = (details) {
debugPrint('onEnd');
};
},
),
},
child: Container()
);
}
}
GestureRecognizer
とListener
使用するFlutter 3.3.0 にアップグレードしても、動作に変化はありません。お父さん78cd2-496d-4661-b6ad-d16604a33473それぞれで呼び出す必要がありますGestureRecognizer
許可する
ジェスチャーを追跡するために使用します。次のコードはパン ジェスチャのコールバックを受け取りません
トラックパッドがスクロールされたとき:
void main() => runApp(Foo());
class Foo extends StatefulWidget {
late final PanGestureRecognizer recognizer;
@override
void initState() {
super.initState();
recognizer = PanGestureRecognizer()
..onStart = _onPanStart
..onUpdate = _onPanUpdate
..onEnd = _onPanEnd;
}
void _onPanStart(DragStartDetails details) {
debugPrint('onStart');
}
void _onPanUpdate(DragUpdateDetails details) {
debugPrint('onUpdate');
}
void _onPanEnd(DragEndDetails details) {
debugPrint('onEnd');
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: recognizer.addPointer,
// recognizer.addPointerPanZoom is not called
child: Container()
);
}
}
タイムライン
リリースされたバージョン: 3.3.0-0.0.pre 安定リリース: 3.3.0
参考文献
API ドキュメント:
GestureDetector
RawGestureDetector
GestureRecognizer
設計書:
- Flutter トラックパッド ジェスチャー
関連する問題:
- 問題 23604
関連する PR:
- フレームワークでトラックパッド ジェスチャをサポートする
- iPadのトラックパッドのジェスチャー
- Linux トラックパッド ジェスチャ
- Mac のトラックパッド ジェスチャ
- Win32 トラックパッド ジェスチャ
- ChromeOS/Android トラックパッド ジェスチャ